package org.mathig.poker;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.mathig.poker.table.Table;
import org.mathig.poker.util.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Engine of the game.<br>
 * Tournament manages many tables.
 * 
 * @author mathig
 */
public class Tournament {

	private Logger logger = LoggerFactory.getLogger(getClass());

	private List<PlayerWrapper> players = new ArrayList<PlayerWrapper>();

	private List<TableListener> tableListeners = new ArrayList<TableListener>();

	public Tournament(List<PlayerWrapper> players) {
		this.players = players;
	}

	public Tournament(PlayerWrapper... players) {
		this.players.addAll(Arrays.asList(players));
	}

	public Tournament(String[] playerClassNames) {
		this.players = loadPlayers(playerClassNames);
	}

	public void addTableListener(TableListener listener) {
		tableListeners.add(listener);
	}

	public void run() {
		if (players.size() < 2)
			throw new IllegalArgumentException("at least 2 players are needed to play !");

		reorderPlayers(players);

		// seat down
		Table table = new Table(5);
		table.seat(players);

	}

	/**
	 * Reorder all players randomly.
	 */
	public void reorderPlayers(List<PlayerWrapper> players) {
		RandomUtils.shuffle(players);
	}

	private static List<PlayerWrapper> loadPlayers(String[] playerClassNames) {
		List<PlayerWrapper> players = new ArrayList<PlayerWrapper>();
		// TODO auto detect all players
		try {
			for (String name : playerClassNames) {
				Class<?> playerClass = Class.forName(name);
				if (!PlayerWrapper.class.isAssignableFrom(playerClass))
					throw new ClassCastException("player class " + playerClass.getName() + " should implement Player interface");

				Object player = playerClass.newInstance();
				players.add((PlayerWrapper) player);
			}
		} catch (ClassNotFoundException e) {
			throw new RuntimeException(e);
		} catch (InstantiationException e) {
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		}

		return players;
	}

}
